﻿using Estela.Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;
using Windows.UI;
using Windows.UI.ApplicationSettings;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace Estela
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private List<String> sílabasPulsadas = new List<string>();

        private string[] teclas = {
            "A","PA","MA","E","PE","ME","I","PI","MI","O","PO","MO","U","PU","MU",
            "BA","DA","ZA","BE","DE","CE","BI","DI","CI","BO","DO","ZO","BU","DU","ZU",
            "RA","GA","LA","RE","GUE","LE","RI","GUI","LI","RO","GO","LO","RU","GU","LU",
            "CA","SA","NA","QUE","SE","NE","QUI","SI","NI","CO","SO","NO","CU","SU","NU",
            "JA","TA","CHA","GE/JE","TE","CHE","GI/JI","TI","CHI","JO","TO","CHO","JU","TU","CHU",
            "YA","FA","LLA","YE","FE","LLE","YI","FI","LLI","YO","FO","LLO","YU","FU","LLU",
            "VA","RRA","HA","VE","RRE","HE","VI","RRI","HI","VO","RRO","HO","VU","RRU","HU",
            "XA","KA","ÑA","XE","KE","ÑE","XI","KI","ÑI","XO","KO","ÑO","XU","KU","ÑU",
            "PLA","FLA","GLA","PLE","FLE","GLE","PLI","FLI","GLI","PLO","FLO","GLO","PLU","FLU","GLU",
            "BLA","CLA","PRA","BLE","CLE","PRE","BLI","CLI","PRI","BLO","CLO","PRO","BLU","CLU","PRU",
            "CRA","DRA","FRA","CRE","DRE","FRE","CRI","DRI","FRI","CRO","DRO","FRO","CRU","DRU","FRU",
            "BRA","TRA","GRA","BRE","TRE","GRE","BRI","TRI","GRI","BRO","TRO","GRO","BRU","TRU","GRU",
            "AL","AR","AN","EL","ER","EN","I","IR","IN","OL","OR","ON","UL","UR","UN",
            "AS","AM","AP","ES","EM","EP","IS","IM","W","OS","OM","OP","US","UM"," ?",
            "B/V","Z","C","G","J","H","M","N","Ñ","T","Y/LL","0","4","5","6",
            "QU/K","D","F","CH","Y","L","P","R/RR","S/X","1","2","3","7","8","9"};

        private Color[] fondos = {
            Colors.Purple,
            Colors.Cyan,
            Colors.Orange,
            Colors.Green,
            Colors.Blue
        };

        private const int columnas = 15;



        public MainPage()
        {
            this.InitializeComponent();
            SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;

            var configuración = Application.Current.Resources["Configuración"] as Configuración;
            configuración.PropertyChanged += configuración_PropertyChanged;

            if (configuración.GuardarÚltimoTexto && SuspensionManager.SessionState.ContainsKey("Sílabas"))
            {
                for (int i = 0; i < (int)SuspensionManager.SessionState["Sílabas"]; i++)
                    sílabasPulsadas.Add((string)SuspensionManager.SessionState[string.Format("Sílaba{0}", i)]);
                FormaCadena();
            }

            RellenaTeclado();
        }

        private void RellenaTeclado()
        {
            Binding binding = new Binding();
            binding.Source = Application.Current.Resources["Configuración"] as Configuración;
            binding.Path = new PropertyPath("TamañoTeclas");

            var filas = teclas.Length / columnas;

            for (int i = 0; i < filas; i++)
                teclado.RowDefinitions.Add(new RowDefinition());

            for (int i = 0; i < columnas; i++)
                teclado.ColumnDefinitions.Add(new ColumnDefinition());

            for (int fila = 0; fila < filas; fila++)
            {
                for (int columna = 0; columna < columnas; columna++)
                {
                    var fondo = new Border();
                    fondo.Tag = new Tuple<int, int>(fila, columna);
                    fondo.PointerReleased += TeclaLiberada;

                    fondo.Background = new SolidColorBrush(fondos[columna / 3]);

                    var fondoBlanco = new Border();
                    fondoBlanco.Background = new SolidColorBrush(Colors.White);
                    fondoBlanco.Margin = new Thickness(4);

                    fondo.Child = fondoBlanco;

                    var texto = new TextBlock();
                    texto.Text = teclas[fila * columnas + columna];
                    texto.Foreground = new SolidColorBrush(Colors.Black);
                    texto.SetBinding(TextBlock.FontSizeProperty, binding);

                    texto.HorizontalAlignment = HorizontalAlignment.Center;
                    texto.VerticalAlignment = VerticalAlignment.Center;

                    fondoBlanco.Child = texto;

                    Grid.SetRow(fondo, fila);
                    Grid.SetColumn(fondo, columna);
                    teclado.Children.Add(fondo);
                }
            }
        }

        void TeclaLiberada(object sender, PointerRoutedEventArgs e)
        {
            var tecla = sender as Border;
            var posición = tecla.Tag as Tuple<int, int>;

            var filas = teclas.Length / columnas;

            int filaMínima = Math.Min(filas - 3, Math.Max(0, posición.Item1 - 1));
            int columnaMínima = Math.Min(columnas - 3, Math.Max(0, posición.Item2 - 1));

            tecladoAmpliado.Children.Clear();

            for (int fila = filaMínima; fila < filaMínima + 3; fila++)
            {
                for (int columna = columnaMínima; columna < columnaMínima + 3; columna++)
                {
                    var teclaPulsada = teclas[fila * columnas + columna];
                    var sílabas = teclaPulsada.Split('/');

                    for (int sílaba = 0; sílaba < sílabas.Length; sílaba++)
                    {
                        var textoSílaba = sílabas[sílaba];

                        var fondo = new Border();
                        fondo.Tag = textoSílaba;

                        fondo.PointerReleased += (s, eventA) =>
                        {
                            flyout.Hide();
                            sílabasPulsadas.Add((s as Border).Tag as string);
                            FormaCadena();
                        };

                        fondo.Background = new SolidColorBrush(fondos[columna / 3]);

                        var fondoBlanco = new Border();
                        fondoBlanco.Background = new SolidColorBrush(Colors.White);
                        fondoBlanco.Margin = new Thickness(30);

                        fondo.Child = fondoBlanco;

                        var texto = new TextBlock();
                        texto.Text = sílabas[sílaba];
                        texto.Foreground = new SolidColorBrush(Colors.Black);
                        texto.FontSize = 96;
                        texto.HorizontalAlignment = HorizontalAlignment.Center;
                        texto.VerticalAlignment = VerticalAlignment.Center;

                        fondoBlanco.Child = texto;

                        Grid.SetRow(fondo, fila - filaMínima);
                        Grid.SetColumn(fondo, (columna - columnaMínima) * 2 + sílaba);
                        if (1 == sílabas.Length)
                            Grid.SetColumnSpan(fondo, 2);
                        tecladoAmpliado.Children.Add(fondo);
                    }
                }
            }

            flyout.ShowAt(this);
        }

        void configuración_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "SubrayarEspacios")
                FormaCadena();
        }

        private void OnCommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs e)
        {
            e.Request.ApplicationCommands.Add(new SettingsCommand(1, "Parámetros", OnParámetros));
        }

        private void OnParámetros(Windows.UI.Popups.IUICommand command)
        {
            var flyout = new ParametersSettingsFlyout();
            flyout.Show();
        }

        private void FormaCadena()
        {
            var configuración = Application.Current.Resources["Configuración"] as Configuración;

            mensaje.Text = string.Empty;

            foreach (var sílaba in sílabasPulsadas)
            {
                if (sílaba == " " && configuración.SubrayarEspacios)
                    mensaje.Text += "_";
                else
                    mensaje.Text += sílaba;
            }

            if (configuración.GuardarÚltimoTexto) { 
                SuspensionManager.SessionState["Sílabas"] = sílabasPulsadas.Count;
                for (int i = 0; i < sílabasPulsadas.Count; i++)
                    SuspensionManager.SessionState[string.Format("Sílaba{0}", i)] = sílabasPulsadas[i];
            }
        }

        private async void Hablar_Click(object sender, RoutedEventArgs e)
        {
            using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
            {
                SpeechSynthesisStream stream = await synthesizer.SynthesizeTextToStreamAsync(mensaje.Text);
                this.mediaElement.SetSource(stream, stream.ContentType);
            }
        }

        private void Deshacer_Click(object sender, RoutedEventArgs e)
        {
            if (sílabasPulsadas.Count > 0)
            {
                var configuración = Application.Current.Resources["Configuración"] as Configuración;
                if (configuración.EliminarUnCarácter)
                {
                    var últimaPulsación = sílabasPulsadas[sílabasPulsadas.Count - 1];
                    últimaPulsación = últimaPulsación.Substring(0, últimaPulsación.Length - 1);

                    if (últimaPulsación.Length == 0)
                        sílabasPulsadas.RemoveAt(sílabasPulsadas.Count - 1);
                    else
                        sílabasPulsadas[sílabasPulsadas.Count - 1] = últimaPulsación;
                }
                else
                {
                    sílabasPulsadas.RemoveAt(sílabasPulsadas.Count - 1);
                }
                FormaCadena();
            }
        }

        private void Espacio_Click(object sender, RoutedEventArgs e)
        {
            sílabasPulsadas.Add(" ");
            FormaCadena();
        }

        private void BorrarTodo_Click(object sender, RoutedEventArgs e)
        {
            sílabasPulsadas.Clear();
            FormaCadena();
        }
    }
}
